im context simple: Protect shared data structures
authorMatthias Clasen <mclasen@redhat.com>
Mon, 18 Jan 2016 18:54:20 +0000 (13:54 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 18 Jan 2016 18:57:39 +0000 (13:57 -0500)
Since a41f02f9b1843e0f0085f801430e55f413a9bf9c, GtkIMContextSimple
uses threads to load X Compose files. It does that every time a new
im context object is initialized, so we can easily end up with multiple
threads accessing the shared global_tables list at the same time.

Use a lock to prevent that.

https://bugzilla.redhat.com/show_bug.cgi?id=1276432

gtk/gtkimcontextsimple.c

index d59189654055d4b5508ed222a177bfa5f2896956..6ec1bda6a505da3bf6a9d9e85a82e769f44f8708 100644 (file)
@@ -83,7 +83,8 @@ const GtkComposeTableCompact gtk_compose_table_compact = {
   6
 };
 
-static GSList          *global_tables;
+G_LOCK_DEFINE_STATIC (global_tables);
+static GSList *global_tables;
 
 static const guint16 gtk_compose_ignore[] = {
   GDK_KEY_Shift_L,
@@ -1227,14 +1228,26 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
     }
   else
     {
+      gboolean success = FALSE;
+
+      G_LOCK (global_tables);
+
       tmp_list = global_tables;
       while (tmp_list)
         {
           if (check_table (context_simple, tmp_list->data, n_compose))
-            return TRUE;
+            {
+              success = TRUE;
+              break;
+            }
           tmp_list = tmp_list->next;
         }
 
+      G_UNLOCK (global_tables);
+
+      if (success)
+        return TRUE;
+
       GTK_NOTE (MISC, {
          g_print ("[ ");
          for (i = 0; i < n_compose; i++)
@@ -1431,8 +1444,12 @@ gtk_im_context_simple_add_table (GtkIMContextSimple *context_simple,
 {
   g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
 
+  G_LOCK (global_tables);
+
   global_tables = gtk_compose_table_list_add_array (global_tables,
                                                     data, max_seq_len, n_seqs);
+
+  G_UNLOCK (global_tables);
 }
 
 /*
@@ -1448,6 +1465,10 @@ gtk_im_context_simple_add_compose_file (GtkIMContextSimple *context_simple,
 {
   g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
 
+  G_LOCK (global_tables);
+
   global_tables = gtk_compose_table_list_add_file (global_tables,
                                                    compose_file);
+
+  G_UNLOCK (global_tables);
 }